package com.hyperf.spring.boot.autoconfigure;

import lombok.Data;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * es自动装配
 *
 * @author lizhaoyang
 */
@Configuration
@ConditionalOnClass({RequestOptions.class, RestClientBuilder.class, RestHighLevelClient.class})
@ConditionalOnProperty(prefix = "hyperf.elastic-search", name = "host")
@EnableConfigurationProperties(ElasticSearchAutoConfiguration.ElasticSearchProperties.class)
public class ElasticSearchAutoConfiguration {

    public static final RequestOptions COMMON_OPTIONS;

    private ElasticSearchProperties properties;

    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();

        // 默认缓存限制为100MB，此处修改为30MB。
        builder.setHttpAsyncResponseConsumerFactory(
                new HttpAsyncResponseConsumerFactory
                        .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
        COMMON_OPTIONS = builder.build();
    }

    public ElasticSearchAutoConfiguration(ElasticSearchProperties properties) {
        this.properties = properties;
    }

    @Bean
    @ConditionalOnMissingBean
    public RestHighLevelClient esRestTemplate() {
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(properties.getUsername(), properties.getPassword()));

        HttpHost httpHost = new HttpHost(properties.getHost(), properties.getPort(), properties.getScheme());
        RestClientBuilder builder = RestClient.builder(httpHost)
                .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));

        return new RestHighLevelClient(builder);
    }

    @Data
    @ConfigurationProperties(prefix = "hyperf.elastic-search")
    public static class ElasticSearchProperties {

        private String username;

        private String password;

        private String host = "127.0.0.1";

        private int port = 9200;

        private String scheme = HttpHost.DEFAULT_SCHEME_NAME;
    }
}
